package states

type State interface {
	OnLock() string
	OnPlay() string
	OnNext() string
	OnPrevious() string
}

var (
	locked  = "locked"
	ready   = "ready"
	playing = "playing"
)

type Player struct {
	State        State
	Playing      bool
	PlayList     []string
	CurrentTrack int
}

func (p *Player) ChangeState(state State) {
	p.State = state
}

func (p *Player) NextTrack() string {
	p.CurrentTrack++
	return "next"
}

func (p *Player) PreviousTrack() string {
	p.CurrentTrack--
	return "previous"
}

type AbstractState struct {
	Player Player
}

// ReadyState 准备状态
type ReadyState struct {
	AbstractState
}

func (r *ReadyState) OnLock() string {
	r.Player.ChangeState(&LockedState{AbstractState{r.Player}})
	return locked
}

func (r *ReadyState) OnPlay() string {
	r.Player.ChangeState(&PlayingState{AbstractState{r.Player}})
	return playing
}

func (r *ReadyState) OnNext() string {
	return "locked"
}

func (r *ReadyState) OnPrevious() string {
	return locked
}

// LockedState 播放器锁定状态
type LockedState struct {
	AbstractState
}

func (l *LockedState) OnLock() string {
	if l.Player.Playing {
		l.Player.ChangeState(&ReadyState{})
	}
	return locked
}

func (l *LockedState) OnPlay() string {
	l.Player.ChangeState(&ReadyState{AbstractState{Player: l.Player}})
	return ready
}

func (l *LockedState) OnNext() string {
	return locked
}

func (l *LockedState) OnPrevious() string {
	return locked
}

type PlayingState struct {
	AbstractState
}

func (p *PlayingState) OnLock() string {
	p.Player.ChangeState(&LockedState{AbstractState{p.Player}})
	return locked
}

func (p *PlayingState) OnPlay() string {
	p.Player.ChangeState(&ReadyState{AbstractState{Player: p.Player}})
	return playing
}

func (p *PlayingState) OnNext() string {
	return p.Player.NextTrack()
}

func (p *PlayingState) OnPrevious() string {
	return p.Player.PreviousTrack()
}
